package br.com.sms.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import br.com.sms.conexao.Conexao;
import br.com.sms.dominio.Cidade;
import br.com.sms.dominio.Destinatario;
import br.com.sms.dominio.MalaDireta;
import br.com.sms.dto.DestinatarioDTO;
import br.com.sms.enuns.UF;
import br.com.sms.util.UtilSQL;


public class DestinatarioDAO {
	private EntityManager manager;
	private Conexao conexao;
	
	public DestinatarioDAO(){
		if(conexao == null)
			conexao = new Conexao();
	}
	
	public Set<Destinatario> recuperarDestinatarios(Cidade cidade, String nome){
		manager =  conexao.getEntityManger();
		String sql = UtilSQL.montarSql(cidade, nome);
		Query query = manager.createQuery(sql);
		UtilSQL.preencherClausula(query, cidade, nome);
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		
		return new HashSet<Destinatario>(lista);
	}
	
	public List<Destinatario> recuperarDestinatarios(UF uf, Cidade cidade, String cep){
		manager =  conexao.getEntityManger();
		String sql = UtilSQL.montarSql(uf, cidade, cep);
		Query query = manager.createQuery(sql);
		UtilSQL.preencherClausula(query, uf, cidade, cep);
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		return lista;
	}
	
	public Destinatario salvar(Destinatario dest) {
		CidadeDAO cidadeDAO = new CidadeDAO();
		Cidade cidadeRecuperada = cidadeDAO.recuperarCidade(dest);
		
		if(cidadeRecuperada == null){
			if(dest.getCidade() != null && dest.getCidade().getUf() != null){
				Cidade cidade = new Cidade(dest.getCidade().getNome(), dest.getCidade().getUf()) ;
				cidade = cidadeDAO.salvar(cidade);
				dest.setCidade(cidade);
			}
		}else{
			dest.setCidade(cidadeRecuperada);
		}
		
		manager = conexao.getEntityManger();
		manager.getTransaction().begin();
		
		if(dest.getId() > 0){
			manager.merge(dest);
		}else{
			manager.persist(dest);
		}
		
		manager.getTransaction().commit();
		conexao.finalizaConexao();
		return dest;
	}

	@SuppressWarnings("unchecked")
	public Set<Destinatario> recuperarDestinatarios(DestinatarioDTO destinatarioDTO) {
		manager = conexao.getEntityManger();
		
		String sql = UtilSQL.montarSql(destinatarioDTO);
		Query query = manager.createQuery(sql);
		UtilSQL.preencherClausula(query, destinatarioDTO);
		
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		
		return new HashSet<Destinatario>(lista);
	}
	
	
	@SuppressWarnings("unchecked")
	public List<Destinatario> recuperarDestinatarios(UF uf){
		manager = conexao.getEntityManger();
		Query query = manager.createQuery("select d from Destinatario d where d.cidade.uf = :uf");
		query.setParameter("uf", uf);
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		return lista;
	}
	
	@SuppressWarnings("unchecked")
	public Set<Destinatario> recuperarDestinatarios(Set<Integer> ids){
		manager = conexao.getEntityManger();
		Query query = manager.createQuery("select d from Destinatario d where d.id in (:ids)");
		query.setParameter("ids", ids);
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		
		return new HashSet<Destinatario>(lista);
	}
	
	@SuppressWarnings("unchecked")
	public Set<Destinatario> recuperarDestinatarios(MalaDireta mala){
		manager = conexao.getEntityManger();
		Query query = manager.createQuery("select d from Destinatario d where d.malasDiretas.id = :malas");
		query.setParameter("malas", mala.getId());
		List<Destinatario> lista = query.getResultList();
		conexao.finalizaConexao();
		
		return new HashSet<Destinatario>(lista);
	}

	public Destinatario recuperarDestinatario(int id) {
		manager = conexao.getEntityManger();
		Destinatario destinatario = manager.find(Destinatario.class, id);
		conexao.finalizaConexao();
			
		return destinatario;
	}
	
	/**
	 * Realiza uma pesquisa na tabela de Destinatarios de acordo 
	 * com a clausula where passada como parâmetro.
	 * @param whereClause
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Destinatario> pesquisar(StringBuffer whereClause) {
		manager = conexao.getEntityManger();
		
		try{
			Query query = manager.createQuery("select d from Destinatario d where " + whereClause.toString());
			return query.getResultList();
		}catch (NoResultException e) {
			return null;
		}
		finally{
			conexao.finalizaConexao();
		}
	}

	public void excluir(Destinatario destinatario) {
		manager = conexao.getEntityManger();
		
		destinatario = recuperarDestinatario(destinatario.getId());
		
		manager.getTransaction().begin();
		manager.remove(destinatario);
		manager.getTransaction().commit();
		conexao.finalizaConexao();
	}

	
}
